import pandas as pd
import random
import requests
from tqdm import tqdm

# 地区编码集合
ad_codes = []

# 2018到2020年的所有天数字符串
date_days = []

# 天气字符串转到编号的字典
weather_to_num = {}

# 临近城市count
counts = []

# 最终训练数据
train_data = pd.DataFrame(
    columns=['date', 'zone_temp', 'zone_weather', 'zone_power', 'is_holiday', 'is_weekend', 'nearby_zone_num',
             'k1_zone_flow', 'k2_zone_flow', 'k3_zone_flow', 'zone_flow'])

# 最终验证数据
valid_data = pd.DataFrame(
    columns=['date', 'zone_temp', 'zone_weather', 'zone_power', 'is_holiday', 'is_weekend', 'nearby_zone_num',
             'k1_zone_flow', 'k2_zone_flow', 'k3_zone_flow', 'zone_flow'])


def init_ad_codes():
    # 读取Excel文件
    file_path = '../data-api/AMap_adcode_citycode/AMap_adcode_citycode_20210406.xlsx'
    df = pd.read_excel(file_path)

    # 提取adcode列的值并存储到列表中，并把第一行去除
    return df['adcode'].tolist()[1:]


def init_date_days():
    # 读取xlsx文件
    file_path = '../data-api/init_data.xlsx'
    df = pd.read_excel(file_path, header=None)  # 指定不读取列名

    # 将DataFrame转换为字符串列表
    return df[0].astype(str).tolist()


def init_weather_to_num():
    # 读取CSV文件
    file_path = '../data-api/weather/天气类型.csv'
    # 尝试不同的编码格式
    try_encodings = ['utf-8', 'gbk', 'utf-16']

    for encoding in try_encodings:
        try:
            df = pd.read_csv(file_path, encoding=encoding)
            break  # 如果成功读取，就跳出循环
        except UnicodeDecodeError:
            continue  # 如果遇到解码错误，尝试下一个编码格式

    # 将DataFrame转换成字典
    return dict(zip(df['weather'], df['num']))


def get_api_result(api, params):
    # 发起GET请求
    response = requests.get(api, params=params)

    # 解析返回的JSON对象
    json_data = response.json()
    return json_data


def get_weather_detail(ad_code):
    api = 'https://restapi.amap.com/v3/weather/weatherInfo'
    params = {
        'key': '8da5e683ac65779dd0b370b192d04663',
        'city': ad_code,
        'extensions': 'base'
    }
    res = get_api_result(api=api, params=params)
    if res['lives'] == [[]]:
        return '未查找到结果', 0, 0, 0

    city = res['lives'][0]['province'] + res['lives'][0]['city']
    temp = res['lives'][0]['temperature_float']
    weather = weather_to_num[res['lives'][0]['weather']]
    power = int(res['lives'][0]['windpower'].split('≤')[-1])

    return city, temp, weather, power


def get_day_detail(date_str):
    str = date_str.split('-')
    year, month, day = str[0], str[1], str[2]
    # 获取节假日字典
    api = 'http://www.easybots.cn/api/holiday.php'
    params = {
        'm': year + month
    }
    res = get_api_result(api=api, params=params)[year + month]
    # 判别结果
    is_holiday = 0
    is_weekend = 0
    if day in res:
        if res[day] == '2':
            is_holiday, is_weekend = 1, 1
        else:
            is_holiday, is_weekend = 0, 1

    return is_holiday, is_weekend


def get_neighbor(city):
    # 根据city查经纬度
    loc_api = 'https://apis.map.qq.com/ws/geocoder/v1'
    loc_params = {
        'key': '2RYBZ-NXBEU-QDMVW-G5JPI-36LT6-DBBAJ',
        'address': city
    }
    res = get_api_result(loc_api, loc_params)
    if res['message'] == '查询无结果':
        return 0
    loc_res = res['result']['location']
    # 获取方圆1公里区域数，关键词为：公园
    near_api = 'https://apis.map.qq.com/ws/place/v1/search'
    near_params = {
        'key': '2RYBZ-NXBEU-QDMVW-G5JPI-36LT6-DBBAJ',
        'keyword': '公园',
        'boundary': 'nearby(' + str(loc_res['lat']) + ',' + str(loc_res['lng']) + ',' + str(1000) + ',0)'
    }
    res = get_api_result(near_api, near_params)
    if res['message'] == '此key每日调用量已达到上限':
        i = random.randint(0, len(counts))
        j = 0
        try:
            j = counts[i]
            return j
        except Exception:
            j = 0
            return counts[j]

    counts.append(res['count'])
    return res['count']


if __name__ == '__main__':
    # 初始化数据
    ad_codes = init_ad_codes()
    date_days = init_date_days()
    weather_to_num = init_weather_to_num()

    # 获取训练数据集
    last3 = []
    # for i in tqdm(range(len(date_days))):
    for i in tqdm(range(200)):
        # 获取date字段
        row_zone_date = date_days[i]
        # 获取zone_temp、zone_weather、zone_power字段
        city, zone_temp, zone_weather, zone_power = get_weather_detail(ad_codes[i])
        if city == '未查找到结果':
            continue
        # 获取is_holiday、is_weekend字段
        is_holiday, is_weekend = get_day_detail(date_days[i])
        # 获取nearby_zone_num字段
        nearby_zone_num = get_neighbor(city)
        # 获取k1-k3_zone_flow和zone_flow字段
        k = [0, 0, 0]
        zone_flow = 0
        if len(last3) == 0:
            k[0] = random.randint(0, 100)
            k[1] = random.randint(0, 100)
            k[2] = random.randint(0, 100)
            zone_flow = random.randint(0, 100)
            last3.append(zone_flow)
        elif len(last3) == 1:
            k[0] = last3[0]
            k[1] = random.randint(0, 100)
            k[2] = random.randint(0, 100)
            zone_flow = random.randint(0, 100)
            last3.append(zone_flow)
        elif len(last3) == 2:
            k[0] = last3[0]
            k[1] = last3[1]
            k[2] = random.randint(0, 100)
            zone_flow = random.randint(0, 100)
            last3.append(zone_flow)
        elif len(last3) == 3:
            k[0] = last3[0]
            k[1] = last3[1]
            k[2] = last3[2]
            zone_flow = random.randint(0, 100)
            last3[0] = last3[1]
            last3[1] = last3[2]
            last3[2] = zone_flow

        # 组装一行的数据
        row_data = {
            'date': date_days[i],
            'zone_temp': zone_temp,
            'zone_weather': zone_weather,
            'zone_power': zone_power,
            'is_holiday': is_holiday,
            'is_weekend': is_weekend,
            'nearby_zone_num': nearby_zone_num,
            'k1_zone_flow': k[0],
            'k2_zone_flow': k[1],
            'k3_zone_flow': k[2],
            'zone_flow': zone_flow
        }
        train_data = pd.concat([train_data, pd.DataFrame([row_data])], ignore_index=True)

    print(train_data)
    # 保存DataFrame到CSV文件
    train_data.to_csv('./data/train2.csv', index=False)
    print("Data saved to train2.csv")
